home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
ICMPCMD.C
< prev
next >
Wrap
Text File
|
1990-06-06
|
5KB
|
254 lines
/* ICMP-related user commands */
#include <stdio.h>
#include "global.h"
#include "icmp.h"
#include "mbuf.h"
#include "netuser.h"
#include "internet.h"
#include "timer.h"
#include "ping.h"
extern char nospace[];
extern char badhost[];
int
doicmpstat()
{
extern struct icmp_errors icmp_errors;
extern struct icmp_stats icmp_stats;
extern char *icmptypes[];
register int i;
printf("ICMP: chksum err %u no space %u icmp %u bdcsts %u\n",
icmp_errors.checksum,icmp_errors.nospace,icmp_errors.noloop,
icmp_errors.bdcsts);
printf("type rcvd sent\n");
for(i=0;i<ICMP_TYPES;i++){
if(icmp_stats.input[i] == 0 && icmp_stats.output[i] == 0)
continue;
printf("%-6u%-6u%-6u",i,icmp_stats.input[i],
icmp_stats.output[i]);
if(icmptypes[i] != NULLCHAR)
printf(" %s",icmptypes[i]);
printf("\n");
}
return 0;
}
/* Hash table list heads */
struct ping *ping[PMOD];
/* Length of ping packets (default to 0) */
static int16 pinglen;
/* Counter for generating seq numbers */
static int16 iclk;
/* Increment counter -- called by low level clock tick */
icmpclk()
{
iclk++;
}
/* Send ICMP Echo Request packets */
doping(argc,argv)
int argc;
char *argv[];
{
int32 dest;
struct ping *add_ping(),*pp1;
register struct ping *pp;
void ptimeout();
int16 hval,hash_ping();
int i;
if(argc < 2){
printf("Host Sent Rcvd %% Avg RTT Interval Length\n");
for(i=0;i<PMOD;i++){
for(pp = ping[i];pp != NULLPING;pp = pp->next){
printf("%-16s",inet_ntoa(pp->remote));
printf("%8lu%8lu",pp->count,pp->echoes);
printf("%4lu%10lu%10lu%8u\n",
(long)pp->echoes * 100 / pp->count,
pp->echoes != 0 ?
TICK2MS(pp->ttotal) / pp->echoes : 0,
TICK2SEC(pp->timer.start),pp->length);
}
}
return 0;
}
if(strcmp(argv[1],"clear") == 0){
for(i=0;i<PMOD;i++){
for(pp = ping[i];pp != NULLPING;pp = pp1){
pp1 = pp->next;
del_ping(pp);
}
}
return 0;
}
if(strcmp(argv[1],"length") == 0){
if(argc < 3)
printf("ping length %u\n",pinglen);
else
pinglen = atoi(argv[2]) % 4096;
return 0;
}
if((dest = resolve(argv[1])) == 0){
printf(badhost,argv[1]);
return 1;
}
/* See if dest is already in table */
hval = hash_ping(dest);
for(pp = ping[hval]; pp != NULLPING; pp = pp->next){
if(pp->remote == dest){
break;
}
}
if(argc > 2){
/* Inter-ping time is specified; set up timer structure */
if(pp == NULLPING)
if ((pp = add_ping(dest)) == NULLPING){
printf(nospace);
return 1;
}
pp->timer.start = SEC2TICK(atol(argv[2]));
pp->timer.func = ptimeout;
pp->timer.arg = (char *)pp;
pp->remote = dest;
pp->length = (argc > 3)? (atoi(argv[3]) % 4096) : pinglen;
start_timer(&pp->timer);
pp->count++;
pingem(dest,iclk,REPEAT,pp->length);
} else
pingem(dest,iclk,ONESHOT,pinglen);
return 0;
}
/* Called by ping timeout */
void
ptimeout(p)
char *p;
{
register struct ping *pp;
/* Send another ping */
pp = (struct ping *)p;
pp->count++;
pingem(pp->remote,iclk,REPEAT,pp->length);
start_timer(&pp->timer);
}
/* Send ICMP Echo Request packet */
static
pingem(dest,seq,id,len)
int32 dest;
int16 seq;
int16 id;
int16 len;
{
struct mbuf *bp,*htonicmp();
struct mbuf *dbp = NULLBUF;
struct icmp icmp;
int i;
extern struct icmp_stats icmp_stats;
if(len != 0){
if((dbp = alloc_mbuf(len)) == NULLBUF){
printf(nospace);
return 0;
}
for(i = 1; i <= len; i++)
dbp->data[i - 1] = uchar(i);
dbp->cnt = len;
}
icmp_stats.output[ECHO_REQ]++;
icmp.type = ECHO_REQ;
icmp.code = 0;
icmp.args.echo.seq = seq;
icmp.args.echo.id = id;
if((bp = htonicmp(&icmp,dbp)) == NULLBUF){
free_p(dbp);
return 0;
}
return ip_send(ip_addr,dest,ICMP_PTCL,0,0,bp,len_mbuf(bp),0,0);
}
/* Called with incoming Echo Reply packet */
int
echo_proc(source,dest,icmp)
int32 source,dest;
struct icmp *icmp;
{
register struct ping *pp;
int16 hval,hash_ping();
long rtt;
if ((rtt = iclk - icmp->args.echo.seq) < 0)
rtt += 65536L;
hval = hash_ping(source);
for(pp = ping[hval]; pp != NULLPING; pp = pp->next)
if(pp->remote == source)
break;
if(pp == NULLPING || icmp->args.echo.id != 1){
printf("%s: echo reply id %u seq %u, %lu ms\n",
inet_ntoa(source),
icmp->args.echo.id,icmp->args.echo.seq,
TICK2MS(rtt));
fflush(stdout);
} else {
/* Repeated poll, just keep stats */
pp->ttotal += rtt;
pp->echoes++;
}
}
static
int16
hash_ping(dest)
int32 dest;
{
int16 hval;
hval = (hiword(dest) ^ loword(dest)) % PMOD;
return hval;
}
/* Add entry to ping table */
static
struct ping *
add_ping(dest)
int32 dest;
{
struct ping *pp;
int16 hval,hash_ping();
pp = (struct ping *)calloc(1,sizeof(struct ping));
if(pp == NULLPING)
return NULLPING;
hval = hash_ping(dest);
pp->prev = NULLPING;
pp->next = ping[hval];
if(pp->next != NULLPING)
pp->next->prev = pp;
ping[hval] = pp;
return pp;
}
/* Delete entry from ping table */
static
del_ping(pp)
struct ping *pp;
{
int16 hval,hash_ping();
stop_timer(&pp->timer);
if(pp->next != NULLPING)
pp->next->prev = pp->prev;
if(pp->prev != NULLPING) {
pp->prev->next = pp->next;
} else {
hval = hash_ping(pp->remote);
ping[hval] = pp->next;
}
free((char *)pp);
}
ə